//
//  main.m
//  08-ios9新特性（Nullability。泛型，_kindof）
//
//  Created by dllo on 16/7/13.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Truck.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
    
    
//
//
    //
    //
    //
    //
    //   
   
    
    Person *per = [[Person alloc] init];
    
    //nonnull 修饰的属性，对应的getter和setter方法
    per.name = nil;
    [per setName:nil];
    per.name = @"llf";
    
    
    //nullable 修饰的属性，对应的getter和seter方法
    
//    [per setSex:<#(NSString * _Nullable)#>];
    [per sex];
    per.sex = nil;
//    [per setFriends:<#(NSArray * _Nullable)#>];
//    [per friends];
    
    
    
//    per setDic:<#(NSDictionary * _Nonnull)#>]
    
    
//   2. 泛型
    //带泛型的容器(规定了容器中所存储的类型)
    //声明一个可变数组，内部存放的都是NSString
//    1.数组中添加其它类型，会有警告
//    2.数组取出来的类型不再是id类型，对应边咸亨声明式的类型
//    3.泛型会改变类的一些方法，使其与生命的类型相同
    NSMutableArray<NSString *>*array = [NSMutableArray arrayWithObjects:@"1", nil];
    NSString *string = array.firstObject;
    NSMutableArray *array1 = [NSMutableArray array];
    array.firstObject.length;
//    [array.firstObject:@"d"];
    [array addObject:@20];
    [array addObject:per];
    NSInteger integer = [array objectAtIndex:0].length;
    
    //带泛型的字典
    NSMutableDictionary<NSString *,NSString *> *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"kd",@"name", nil];
    [dic objectForKey:@"name"].length;
//    [dic ob]
    
    
    //自定义泛型
    
    Truck<Student *> *truckStu = [[Truck alloc] init];
    [truckStu addObject:per];
    Truck<Person *> *truckPer = [[Truck alloc] init];
    
    Student *stu = [[Student alloc] init];
    stu.stuNumber = @"001";
    
    [truckStu addObject:stu];
    [truckPer addObject:per];
    
//    NSArray
    
    //协变性和逆变性
    Truck *truck = nil;
    Truck<NSArray *> *truck1 = nil;
    Truck<NSMutableArray *>*truck2 = nil;
    //大类型（任意类型）可以给有反省的赋值
//    也可以有泛型的给他赋值
    truck = truck1;
    truck = truck2;
     truck1 = truck2;
     truck2 = truck1;
    //__covariant协变性 子类在给父类赋值时自动强转
//    Truck<NSArray *>  与Truck<NSMutableArray *>
    
//    逆变 __contravariant 逆变性 父类给子类赋值，自动强转（暂时不知道应用于何处）
    truck1 = truck2;
    truck2 = truck1;
    
    
    
    //3__kindof
    Truck *truckKindOf = [[Truck alloc] init];
    NSMutableArray *arr = (NSMutableArray *)[truckKindOf returnArray];
//    加_kindof修饰后，返回的类型及其子类型，都可以接受这个返回值
    NSArray *arr1 = [truckKindOf returnArray];
    NSMutableArray *arr2 = (NSMutableArray *)arr1;
    
    
    
    
    
    
    
    
    
    
    return 0;
}
